home *** CD-ROM | disk | FTP | other *** search
/ C & C++ Multimedia Cyber Classroom / C and C++ Multimedia Cyber Classroom (Prentice Hall) (1998).iso / cpphtp2 / code.jar / code / ch15 / fig15_03.txt next >
Text File  |  1998-02-27  |  8KB  |  268 lines

  1. 1   // Fig. 15.3: listnd.h
  2. 2   // ListNode template definition
  3. 3   #ifndef LISTND_H
  4. 4   #define LISTND_H
  5. 5   
  6. 6   template< class NODETYPE > class List;  // forward declaration
  7. 7   
  8. 8   template<class NODETYPE>
  9. 9   class ListNode {
  10. 10     friend class List< NODETYPE >; // make List a friend
  11. 11  public:
  12. 12     ListNode( const NODETYPE & );  // constructor
  13. 13     NODETYPE getData() const;      // return data in the node
  14. 14  private:
  15. 15     NODETYPE data;                 // data
  16. 16     ListNode< NODETYPE > *nextPtr; // next node in the list
  17. 17  };
  18. 18  
  19. 19  // Constructor
  20. 20  template<class NODETYPE>
  21. 21  ListNode< NODETYPE >::ListNode( const NODETYPE &info )
  22. 22     : data( info ), nextPtr( 0 ) { }
  23. 23  
  24. 24  // Return a copy of the data in the node
  25. 25  template< class NODETYPE >
  26. 26  NODETYPE ListNode< NODETYPE >::getData() const { return data; }
  27. 27  
  28. 28  #endif
  29. 29  
  30. 30  
  31. 31  // Fig. 15.3: list.h
  32. 32  // Template List class definition
  33. 33  #ifndef LIST_H
  34. 34  #define LIST_H
  35. 35  
  36. 36  #include <iostream.h>
  37. 37  #include <assert.h>
  38. 38  #include "listnd.h"
  39. 39  
  40. 40  template< class NODETYPE >
  41. 41  class List {
  42. 42  public:
  43. 43     List();      // constructor
  44. 44     ~List();     // destructor
  45. 45     void insertAtFront( const NODETYPE & );
  46. 46     void insertAtBack( const NODETYPE & );
  47. 47     bool removeFromFront( NODETYPE & );
  48. 48     bool removeFromBack( NODETYPE & );
  49. 49     bool isEmpty() const;
  50. 50     void print() const;
  51. 51  private:
  52. 52     ListNode< NODETYPE > *firstPtr;  // pointer to first node
  53. 53     ListNode< NODETYPE > *lastPtr;   // pointer to last node
  54. 54  
  55. 55     // Utility function to allocate a new node
  56. 56     ListNode< NODETYPE > *getNewNode( const NODETYPE & );
  57. 57  };
  58. 58  
  59. 59  // Default constructor
  60. 60  template< class NODETYPE >
  61. 61  List< NODETYPE >::List() : firstPtr( 0 ), lastPtr( 0 ) { }
  62. 62  
  63. 63  // Destructor
  64. 64  template< class NODETYPE >
  65. 65  List< NODETYPE >::~List()
  66. 66  {
  67. 67     if ( !isEmpty() ) {    // List is not empty
  68. 68        cout << "Destroying nodes ...\n";
  69. 69  
  70. 70        ListNode< NODETYPE > *currentPtr = firstPtr, *tempPtr;
  71. 71  
  72. 72        while ( currentPtr != 0 ) {  // delete remaining nodes
  73. 73           tempPtr = currentPtr;
  74. 74           cout << tempPtr->data << '\n';
  75. 75           currentPtr = currentPtr->nextPtr;
  76. 76           delete tempPtr;
  77. 77        }
  78. 78     }
  79. 79  
  80. 80     cout << "All nodes destroyed\n\n";
  81. 81  }
  82. 82  
  83. 83  // Insert a node at the front of the list
  84. 84  template< class NODETYPE >
  85. 85  void List< NODETYPE >::insertAtFront( const NODETYPE &value )
  86. 86  {
  87. 87     ListNode< NODETYPE > *newPtr = getNewNode( value );
  88. 88  
  89. 89     if ( isEmpty() )  // List is empty
  90. 90        firstPtr = lastPtr = newPtr;
  91. 91     else {          // List is not empty
  92. 92        newPtr->nextPtr = firstPtr;
  93. 93        firstPtr = newPtr;
  94. 94     }
  95. 95  }
  96. 96  
  97. 97  // Insert a node at the back of the list
  98. 98  template< class NODETYPE >
  99. 99  void List< NODETYPE >::insertAtBack( const NODETYPE &value )
  100. 100 {
  101. 101    ListNode< NODETYPE > *newPtr = getNewNode( value );
  102. 102 
  103. 103    if ( isEmpty() )  // List is empty
  104. 104       firstPtr = lastPtr = newPtr;
  105. 105    else {          // List is not empty
  106. 106       lastPtr->nextPtr = newPtr;
  107. 107       lastPtr = newPtr;
  108. 108    }
  109. 109 }
  110. 110 
  111. 111 // Delete a node from the front of the list
  112. 112 template< class NODETYPE >
  113. 113 bool List< NODETYPE >::removeFromFront( NODETYPE &value )
  114. 114 {
  115. 115    if ( isEmpty() )             // List is empty
  116. 116       return false;             // delete unsuccessful
  117. 117    else {
  118. 118       ListNode< NODETYPE > *tempPtr = firstPtr;
  119. 119 
  120. 120       if ( firstPtr == lastPtr )
  121. 121          firstPtr = lastPtr = 0;
  122. 122       else
  123. 123          firstPtr = firstPtr->nextPtr;
  124. 124 
  125. 125       value = tempPtr->data;  // data being removed
  126. 126       delete tempPtr;
  127. 127       return true;            // delete successful
  128. 128    }
  129. 129 }
  130. 130 
  131. 131 // Delete a node from the back of the list
  132. 132 template< class NODETYPE >
  133. 133 bool List< NODETYPE >::removeFromBack( NODETYPE &value )
  134. 134 {
  135. 135    if ( isEmpty() )
  136. 136       return false;   // delete unsuccessful
  137. 137    else {
  138. 138       ListNode< NODETYPE > *tempPtr = lastPtr;
  139. 139 
  140. 140       if ( firstPtr == lastPtr )
  141. 141          firstPtr = lastPtr = 0;
  142. 142       else {
  143. 143          ListNode< NODETYPE > *currentPtr = firstPtr;
  144. 144 
  145. 145          while ( currentPtr->nextPtr != lastPtr )
  146. 146             currentPtr = currentPtr->nextPtr;
  147. 147 
  148. 148          lastPtr = currentPtr;
  149. 149          currentPtr->nextPtr = 0;
  150. 150       }
  151. 151 
  152. 152       value = tempPtr->data;
  153. 153       delete tempPtr;
  154. 154       return true;   // delete successful
  155. 155    }
  156. 156 }
  157. 157 
  158. 158 // Is the List empty?
  159. 159 template< class NODETYPE > 
  160. 160 bool List< NODETYPE >::isEmpty() const 
  161. 161    { return firstPtr == 0; }
  162. 162 
  163. 163 // Return a pointer to a newly allocated node
  164. 164 template< class NODETYPE >
  165. 165 ListNode< NODETYPE > *List< NODETYPE >::getNewNode( 
  166. 166                                         const NODETYPE &value )
  167. 167 {
  168. 168    ListNode< NODETYPE > *ptr = 
  169. 169       new ListNode< NODETYPE >( value );
  170. 170    assert( ptr != 0 );
  171. 171    return ptr;
  172. 172 }
  173. 173 
  174. 174 // Display the contents of the List
  175. 175 template< class NODETYPE >
  176. 176 void List< NODETYPE >::print() const
  177. 177 {
  178. 178    if ( isEmpty() ) {
  179. 179       cout << "The list is empty\n\n";
  180. 180       return;
  181. 181    }
  182. 182 
  183. 183    ListNode< NODETYPE > *currentPtr = firstPtr;
  184. 184 
  185. 185    cout << "The list is: ";
  186. 186 
  187. 187    while ( currentPtr != 0 ) {
  188. 188       cout << currentPtr->data << ' ';
  189. 189       currentPtr = currentPtr->nextPtr;
  190. 190    }
  191. 191 
  192. 192    cout << "\n\n";
  193. 193 }
  194. 194 
  195. 195 #endif
  196. 196 
  197. 197 
  198. 198 // Fig. 15.3: fig15_03.cpp
  199. 199 // List class test
  200. 200 #include <iostream.h>
  201. 201 #include "list.h"
  202. 202 
  203. 203 // Function to test an integer List
  204. 204 template< class T >
  205. 205 void testList( List< T > &listObject, const char *type )
  206. 206 {
  207. 207    cout << "Testing a List of " << type << " values\n";
  208. 208 
  209. 209    instructions();
  210. 210    int choice;
  211. 211    T value;
  212. 212 
  213. 213    do {
  214. 214       cout << "? ";
  215. 215       cin >> choice;
  216. 216 
  217. 217       switch ( choice ) {
  218. 218          case 1:
  219. 219             cout << "Enter " << type << ": ";
  220. 220             cin >> value;
  221. 221             listObject.insertAtFront( value );
  222. 222             listObject.print();
  223. 223             break;
  224. 224          case 2:
  225. 225             cout << "Enter " << type << ": ";
  226. 226             cin >> value;
  227. 227             listObject.insertAtBack( value );
  228. 228             listObject.print();
  229. 229             break;
  230. 230          case 3:
  231. 231             if ( listObject.removeFromFront( value ) )
  232. 232                cout << value << " removed from list\n";
  233. 233 
  234. 234             listObject.print();
  235. 235             break;
  236. 236          case 4:
  237. 237             if ( listObject.removeFromBack( value ) )
  238. 238                cout << value << " removed from list\n";
  239. 239 
  240. 240             listObject.print();
  241. 241             break;
  242. 242       }
  243. 243    } while ( choice != 5 );
  244. 244 
  245. 245    cout << "End list test\n\n";
  246. 246 }
  247. 247 
  248. 248 void instructions()
  249. 249 {
  250. 250    cout << "Enter one of the following:\n"
  251. 251         << "  1 to insert at beginning of list\n" 
  252. 252         << "  2 to insert at end of list\n" 
  253. 253         << "  3 to delete from beginning of list\n" 
  254. 254         << "  4 to delete from end of list\n" 
  255. 255         << "  5 to end list processing\n";
  256. 256 }
  257. 257 
  258. 258 int main()
  259. 259 {
  260. 260    List< int > integerList;
  261. 261    testList( integerList, "integer" ); // test integerList
  262. 262 
  263. 263    List< float > floatList;
  264. 264    testList( floatList, "float" );     // test integerList
  265. 265 
  266. 266    return 0;
  267. 267 }
  268.